package com.mangofactory.aop.configuration
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import mx.core.FlexGlobals;
	
	import org.as3commons.bytecode.proxy.ClassProxyInfo;
	import org.as3commons.bytecode.proxy.ProxyFactory;
	import org.as3commons.bytecode.reflect.ByteCodeType;
	import org.as3commons.bytecode.reflect.ByteCodeTypeProvider;

	[Event(name="complete",type="flash.events.Event")]
	public class AspectContainer extends EventDispatcher
	{
		private var classProxyDefinitions:Vector.<ClassProxyDefinition> = new Vector.<ClassProxyDefinition>();
		private var proxyFactory:ProxyFactory;
		public function AspectContainer(proxyFactory:ProxyFactory)
		{
			this.proxyFactory = proxyFactory;
		}

		public function newInstance(clazz:Class,constructorArgs:Array=null):*
		{
			return proxyFactory.createProxy(clazz,constructorArgs);
		}

		public function addProxyDefinitions(proxyDefinitions:Vector.<ClassProxyDefinition>):void
		{
			for each (var proxyDefinition:ClassProxyDefinition in proxyDefinitions)
			{
				addProxyDefinition(proxyDefinition);
			}
		}

		private function addProxyDefinition(proxyDefinition:ClassProxyDefinition):void
		{
			classProxyDefinitions.push(proxyDefinition);
		}
		private function createProxy(proxyDefinition:ClassProxyDefinition):void
		{
			var classProxy:ClassProxyInfo = proxyFactory.defineProxy(proxyDefinition.getClass());
			classProxy.interceptorFactory = new InterceptorFactory(proxyDefinition);
			for each (var methodProxyDefinition:MethodProxyDefinition in proxyDefinition.methodProxyDefinitions)
			{
				classProxy.proxyMethod(methodProxyDefinition.methodName);
			}
		}

		internal function initalize():void
		{
			ByteCodeType.fromLoader(FlexGlobals.topLevelApplication.loaderInfo);
			for each (var proxyDefinition:ClassProxyDefinition in classProxyDefinitions)
			{
				createProxy(proxyDefinition);
			}
			proxyFactory.generateProxyClasses();
			proxyFactory.addEventListener(Event.COMPLETE,onComplete);
			proxyFactory.loadProxyClasses();
		}

		private function onComplete(event:Event):void
		{
			dispatchEvent(event);
		}
	}
}